/*
* 2016.01.23
* triac.c
* 晶闸管驱动
*/

#include "stm32f1xx_hal.h"
#include "tim.h"
#include "pinname.h"
#include "cmsis_os.h"
#include "user.h"

#define uS_DELAY_OFF 100  // 1ms
#define HALF_T1 1000  // 10ms
#define EXCHANGE_DELAY 450
#define FULL_DELAY 150


/* 变量定义 */

static __IO Triac triac_cur = {0}; 

static __IO uint8_t smoke_start = 0;
static __IO uint8_t exchange_start = 0;

// 延时表×20ms
//                          0    1    2    3    4    5    6    7    8    9  */
uint16_t table_delay[10] = {660, 640, 630, 615, 600, 575, 550, 500, 475, 450};
/* 外部变量引用 */
extern osPoolId  pool_TriacHandle;
extern osMessageQId Q_TriacHandle;

/* 过零点触发中断 回调函数 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{    
  if (GPIO_Pin != ZERO) return;
  //if (smoke_is_busy || exchange_is_busy) return;
  
  // 在下半波时处理
  
  // 检查Q_Triac队列，更新输出的控制状态  
  // 读取值
  osEvent evt = osMessageGet(Q_TriacHandle, 0);
  if (evt.status == osEventMessage) {  
    Triac *p = (Triac *)evt.value.p;  
    // 全速启动
    // smoke exchange
    if (!triac_cur.fan_smoke_is_on && p->fan_smoke_is_on) {
      exchange_start = FULL_DELAY; 
    }
    if (!triac_cur.fan_exchange_is_on && p->fan_exchange_is_on) {
      smoke_start = FULL_DELAY; 
    }	
    // 更新 triac_cur
    triac_cur = *p;
    
    // 返还内存
    osPoolFree(pool_TriacHandle, p);
  }
  
  /*----------------------------------------------------------------------------*/ 
  
  
  /* 输出: 条件判断  */  
  uint16_t delay = 4500;
  /* - 排烟通道 */
  if (triac_cur.fan_smoke_is_on) {    
    if (smoke_start > 1) {
      smoke_start--;
      ON_SMOKE;
      
      if (smoke_start == 0) {
        OFF_SMOKE;
      }
    } else {      
      // 最低延时2.5ms，最高延时6ms
      if (triac_cur.fan_smoke_power<10) {
        delay = table_delay[triac_cur.fan_smoke_power];
      } else {
        delay = triac_cur.fan_smoke_power;
      }
      
      __HAL_TIM_SET_COUNTER(&htim2, 0);
      __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, (uint16_t)(delay)); 
      __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, (uint16_t)(delay+uS_DELAY_OFF));
      __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, (uint16_t)(delay+HALF_T1));
      __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, (uint16_t)(delay+HALF_T1+uS_DELAY_OFF));
      
      HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_1);
      HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_2);
      HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_3);
      HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_4);
      
      //smoke_is_busy = true;
    }
    
  }
  // 排烟全速时，按键停止
  if (smoke_start>0 && !triac_cur.fan_smoke_is_on) {
    OFF_SMOKE;	  
  }
  
  
  /* - 循环通道 */
  if (triac_cur.fan_exchange_is_on) {
    //if(1) {
    // 换风延时
    if (exchange_start > 1) {
      exchange_start--;
      ON_EXCHANGE;
      
      if (exchange_start == 0) {
        OFF_EXCHANGE;
      }
    } else {
      __HAL_TIM_SET_COUNTER(&htim4, 0);    
      __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, (uint16_t)(triac_cur.fan_exchange_power));  // 4500
      __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, (uint16_t)(triac_cur.fan_exchange_power + uS_DELAY_OFF));
      __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, (uint16_t)(triac_cur.fan_exchange_power + HALF_T1));
      __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4, (uint16_t)(triac_cur.fan_exchange_power + HALF_T1 + uS_DELAY_OFF));
      
      HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_1);
      HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_2);
      HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_3);
      HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_4);
      
      //exchange_is_busy = true;
    }
  } // if 1
  
  // 交换全速时，按键停止
  if (exchange_start>0 && !triac_cur.fan_exchange_is_on) {
    OFF_EXCHANGE;	  
  } 
  //
}

/*----------------------------------------------------------------------------*/

/* TIME 中断回调函数 */
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
  
  /* TIM2 */
  if (htim->Instance == TIM2) {
    
    // 排烟风机 通道
    switch(htim->Channel) {
      
    case HAL_TIM_ACTIVE_CHANNEL_1:
      ON_SMOKE;
      HAL_TIM_OC_Stop_IT(&htim2, TIM_CHANNEL_1);
      break;
      
    case HAL_TIM_ACTIVE_CHANNEL_2:
      OFF_SMOKE;
      HAL_TIM_OC_Stop_IT(&htim2, TIM_CHANNEL_2);
      break;
      
    case HAL_TIM_ACTIVE_CHANNEL_3:
      ON_SMOKE;
      HAL_TIM_OC_Stop_IT(&htim2, TIM_CHANNEL_3);
      break;
      
    case HAL_TIM_ACTIVE_CHANNEL_4:
      OFF_SMOKE;
      HAL_TIM_OC_Stop_IT(&htim2, TIM_CHANNEL_4);
      
      //smoke_is_busy = false;
      break;
    }
  }
  
  /* TIM4 */
  if (htim->Instance == TIM4) {
    
    // 循环风机 通道
    switch(htim->Channel) {
      
    case HAL_TIM_ACTIVE_CHANNEL_1:
      ON_EXCHANGE;
      HAL_TIM_OC_Stop_IT(&htim4, TIM_CHANNEL_1);
      break;
      
    case HAL_TIM_ACTIVE_CHANNEL_2:
      OFF_EXCHANGE;
      HAL_TIM_OC_Stop_IT(&htim4, TIM_CHANNEL_2);
      break;
      
    case HAL_TIM_ACTIVE_CHANNEL_3:
      ON_EXCHANGE;
      HAL_TIM_OC_Stop_IT(&htim4, TIM_CHANNEL_3);
      break;
      
    case HAL_TIM_ACTIVE_CHANNEL_4:
      OFF_EXCHANGE;
      HAL_TIM_OC_Stop_IT(&htim4, TIM_CHANNEL_4);
      
      //smoke_is_busy = false;
      break;
    }  
  }
  
}
